package priv.pfz.basedao.jdbctemplate.sqlprovider;

import com.google.common.collect.Lists;
import priv.pfz.basedao.Utils;
import priv.pfz.basedao.info.DaoInfo;
import priv.pfz.basedao.info.FieldInfo;
import priv.pfz.basedao.jdbctemplate.SqlResult;
import priv.pfz.basedao.sharding.ShardingInfo;
import priv.pfz.basedao.sharding.ShardingManager;
import priv.pfz.basedao.sqlbuilder.SQL;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * UPDATE table SET a=entity.a, b=entity.b
 * WHERE (b=example1.b AND c=example1.c) OR (c=example2.c AND d=example2.d) OR ...
 * @author yyjxp
 * 2024/1/28 23:55
 */
public class UpdateByExamplesSqlProvider extends BaseSqlProvider {

    public static <Entity> SqlResult provideSql(Entity entity, Iterable<Entity> examples, ShardingInfo shardingInfo,
                                                DaoInfo daoInfo) {
        Utils.checkNotNull(entity, "entity不能为空");
        Utils.checkNotEmpty(examples, "examples不能为空");
        Map<String, Object> valueMap = getValueMap(daoInfo, entity);
        Utils.checkNotEmpty(valueMap, "entity字段不能全部为空");
        ShardingManager shardingManager = new ShardingManager(daoInfo, shardingInfo);
        List<Object> argList = Lists.newArrayList();

        SQL sql = new SQL();
        for (FieldInfo fieldInfo : daoInfo.getFieldInfos()) {
            if (!valueMap.containsKey(fieldInfo.getFieldName())) {
                continue;
            }
            sql.SET(getFieldEquals(fieldInfo));
            Object value = valueMap.get(fieldInfo.getFieldName());
            argList.add(value);
        }
        List<String> allConditions = new ArrayList<>();
        Iterator<?> iterator = examples.iterator();
        for (int i = 0; iterator.hasNext(); i++) {
            Object example = iterator.next();
            List<String> conditions = new ArrayList<>();
            Map<String, Object> exampleValueMap = getValueMap(daoInfo, example);
            Utils.checkNotEmpty(exampleValueMap, "examples[{0}]字段不能全部为空", i);
            for (FieldInfo fieldInfo : daoInfo.getFieldInfos()) {
                if (!exampleValueMap.containsKey(fieldInfo.getFieldName())) {
                    continue;
                }
                conditions.add(getFieldEquals(fieldInfo));
                Object value = exampleValueMap.get(fieldInfo.getFieldName());
                shardingManager.addShardingInfo(fieldInfo, value);
                argList.add(value);
            }
            allConditions.add(String.join(" AND ", conditions));
        }
        sql.WHERE(String.join(" OR ", allConditions));
        if (daoInfo.isEnableLogicDelete()) {
            sql.AND();
            sql.WHERE(getLogicDeleteWhere(daoInfo));
        }
        sql.UPDATE(shardingManager.getShardingTable());
        String sqlStr = sql.toString();
        sqlStr += shardingManager.getThirdShardingStr();

        System.out.println(sqlStr);
        System.out.println(argList);
        return new SqlResult(sqlStr, argList);
    }
}
